import { AddressInfo, WebSocketServer, WebSocket } from 'ws'
import log from 'electron-log'
import { delay } from '../utils'
import { encode, decode } from '@msgpack/msgpack'
// 创建WebSocket服务器，监听50001端口
// const dataString = localStorage.getItem('fileContent')
// const data = dataString ? dataString : [];

// 0 JSON.stringify  1 msgpack
export const SEND_TYPE = 0 as number

export default class WsServer {
  public WsArray: WebSocket[] = []
  public wss: WebSocketServer | null = null

  constructor(wssport: number) {
    // 创建 WebSocket 服务器
    this.wss = this.createWebsocket(wssport)
  }
  public createWebsocket = (wssport: number) => {
    if (this.wss) {
      return this.wss
    }

    // 创建 WebSocket 服务器
    const wss = new WebSocketServer({
      port: wssport || 50001,
      perMessageDeflate: {
        zlibDeflateOptions: {
          chunkSize: 1024, // 每次压缩的块大小（字节）
          memLevel: 7, // 内存使用级别（1-9，默认7）
          level: 3 // 压缩级别（0-9，0=不压缩，9=最高压缩）
        },
        zlibInflateOptions: {
          chunkSize: 10 * 1024 // 解压块大小
        },
        clientNoContextTakeover: true, // 客户端不保留压缩上下文（节省内存）
        serverNoContextTakeover: true, // 服务端不保留压缩上下文
        concurrencyLimit: 10, // 并发压缩限制
        threshold: 1024 // 仅当消息大小 >1KB 才压缩
      }
    })

    wss.on('listening', () => {
      const address = wss.address()
      if (address) {
        log.info(`WebSocket 服务器已启动并监听端口 ${(address as AddressInfo).port}`)
      } else {
        log.error('无法获取 WebSocket 服务器的地址')
      }
    })
    wss.on('connection', async (ws: WebSocket) => {
      this.WsArray.push(ws)
      log.info(`会回客户端连接成功，共${this.WsArray.length ?? 0} 个`)
      globalThis.mainWindow.webContents.send('render-client-isConnected', true)

      // 先发送to_connect
      this.sendMessage({
        type: 'to_connect',
        ppid: process.pid,
        platform: globalThis.targetPlatform,
        aiHosts: 'https://test.zhihuige.cc/csrserver',
        huihuiHosts: 'https://test.zhihuige.cc/csrc/api/v1',
      })

      globalThis.mainWindow.webContents.send('render-log', {
        type: 'to_connect',
        message: `初始化平台参数已完成：${globalThis.targetPlatform}`,
        tagType: 'success',
        from: 1
      })

      globalThis.autoSend && this.sendBaseMessage()

      // 监听来自客户端的消息
      ws.on('message', async (message: any) => {
        const json_message = SEND_TYPE == 0 ? JSON.parse(message) : decode(message) as any
        log.info('收到会回客户端发送过来的消息', json_message)
        console.log('收到客户端发送过来的消息', json_message)
        // 分发会回客户端发送过来的消息
        switch (json_message.type) {
          case 'message':
            // 解析出csrName，给对应的千牛ws发送消息
            if (!globalThis.fileData) {
              globalThis.mainWindow.webContents.send('render-log', {
                type: 'no-file-data',
                message: `文件数据为空（请先导入文件）`
              })
              return
            }
            const { act } = json_message
            if (act == 'getCurrentCsr') {
              const curretCsrData = globalThis.fileData?.find(
                (item: any) => item?.content?.type == 'currentCsr'
              )
              console.log(curretCsrData)
              curretCsrData && ws.send(SEND_TYPE == 0 ? JSON.stringify(curretCsrData) : encode(curretCsrData))
            } else if (act == 'getCurrentConv') {
              const curretConvData = globalThis.fileData?.find(
                (item: any) => item?.content?.type == 'currentConv'
              )
              console.log(curretConvData)
              curretConvData && ws.send(SEND_TYPE == 0 ? JSON.stringify(curretConvData) : encode(curretConvData))
            } else if (act == 'getRemoteHisMsg') {
              const remoteHisMsgData = globalThis.fileData?.find(
                (item: any) =>
                  item?.content?.type == 'message' || item?.content?.type == 'remote_his_message'
              )
              const cloneData = JSON.parse(JSON.stringify(remoteHisMsgData))
              cloneData.content && (cloneData.content.type = 'remote_his_message')
              cloneData && ws.send(SEND_TYPE == 0 ? JSON.stringify(cloneData) : encode(cloneData))
            }
            globalThis.mainWindow.webContents.send('render-log', {
              type: 'client-message',
              message: JSON.stringify(json_message),
              tagType: 'info',
              from: 2
            })

            break

          // 向9996发送消息
          case 'ToSend':
            globalThis.mainWindow.webContents.send('render-log', {
              type: 'ToSend',
              message: JSON.stringify(json_message),
              tagType: 'info',
              from: 2
            })
            break
          default:
            globalThis.mainWindow.webContents.send('render-log', {
              type: json_message?.type ?? 'unkown',
              message: JSON.stringify(json_message),
              tagType: 'info',
              from: 2
            })
            break
        }
      })
      ws.on('close', () => {
        log.info('会回客户端WebSocket关闭')
        this.WsArray.splice(this.WsArray.indexOf(ws), 1)
        !globalThis.exit &&
          globalThis.mainWindow.webContents.send('render-log', {
            type: 'close',
            message: `客户端WebSocket断开连接`,
            tagType: 'info',
            from: 2
          })
        !globalThis.exit &&
          globalThis.mainWindow.webContents.send('render-client-isConnected', false)
      })
      ws.on('ping', () => {
        console.log('会回客户端WebSocket ping')
      })
    })
    wss.on('error', (error) => {
      log.error('会回客户端WebSocket 服务器错误:', error)
    })

    // 服务端关闭时
    wss.on('close', () => {
      // 给每个客户端发送关闭消息
      this.WsArray.forEach((ws) => {
        ws?.send(JSON.stringify({ type: 'to_close', control_window: 'close' }))
      })
    })
    return wss
  }

  /**
   * 发送消息
   * @param data
   */
  public sendMessage = (data: any) => {
    if (!data) return
    console.log('会回客户端WebSocket 发送消息:', data)
    const ws = this.WsArray[0]
    if (!ws) {
      return
    }
    // console.log('ws:', ws)
    ws.send(SEND_TYPE == 0 ? JSON.stringify(data) : encode(data))
    globalThis.mainWindow.webContents.send('render-log', {
      type: 'sendMessage',
      message: JSON.stringify(data),
      tagType: 'success',
      data,
      from: 1
    })
  }

  /**
   * 检查是否有客户端连接
   * @returns
   */
  public checkWs = () => {
    return this.WsArray.length > 0
  }

  /**
   * 关闭WebSocket服务器
   */
  public close = () => {
    this.wss?.close()
  }

  /**
   * 关闭所有客户端连接
   */
  public closeAll = () => {
    this.WsArray.forEach((ws) => {
      ws?.send(SEND_TYPE == 0 ? JSON.stringify({ type: 'to_close', control_window: 'close' }) : encode({ type: 'to_close', control_window: 'close' }))
      ws?.close()
    })
    this.WsArray = []
  }

  /**
   * 发送基础消息
   */
  public sendBaseMessage = async () => {
    // 发送currentCsr
    const curretCsrData = globalThis.fileData?.find(
      (item: any) => item?.content?.type == 'currentCsr'
    )
    this.sendMessage(curretCsrData)

    await delay(1000)

    // 发送currentConv
    const curretConvData = globalThis.fileData?.find(
      (item: any) => item?.content?.type == 'currentConv'
    )
    this.sendMessage(curretConvData)

    await delay(1000)

    // 发送remote_his_message
    const remoteHisMsgData = globalThis.fileData?.find(
      (item: any) => item?.content?.type == 'message'
    )
    const cloneData = JSON.parse(JSON.stringify(remoteHisMsgData))
    cloneData.content && (cloneData.content.type = 'remote_his_message')
    this.sendMessage(cloneData)
  }
}
